
#include "commmsg.h"
#include "../mainctrl.h"
#include "../cmd/dataprepare.h"
#include "cmdqqmall.h"
#include "../cmd/cmdapi.h"
#include "../qqmall/CQQMallConfig.h"

CT_REGISTER_ASYNCCMD(ID_MAIN_QQ_MALL, CCmdQQMall);

int CCmdQQMall::Do(void* pData)
{
    //解析消息
    CCmdPBDoParam* pstParam = (CCmdPBDoParam*) pData;
    pstMainCtrl = (CMainCtrl*) pstParam->m_pMain;

    if (pstParam->m_pstMsgHead->msgid() != ID_MAIN_QQ_MALL ||
        pstParam->m_pstMsgHead->msgtype() != CSMsgDef::EMT_REQUEST)
    {
        CT_ERROR(("Cmd Stat Err Cmd=%d CmdID=%d Tpye=%d",
            ID_MAIN_QQ_MALL,
            pstParam->m_pstMsgHead->msgid(),
            pstParam->m_pstMsgHead->msgtype()));
        return Done(RET_SYS_ERROR);
    }

    stMsgHead = *(pstParam->m_pstMsgHead);
    stEnpHead = *(pstParam->m_pstEnpHead);
    int iRet = pstMainCtrl->DecodePBMsg(stReq, pstParam);
    if (iRet)
    {
        return AnsClients(iRet);
    }
    //消息解析结束

    //检查登录
    uiGID = stReq.gid();
    iRet = pstMainCtrl->CheckLogin(uiGID, stEnpHead);
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    LogicDo(RET_OK);
    return RET_OK;
}

int CCmdQQMall::LogicDo(int iRet)
{
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    PREPARE_PLAYER_BASE_INFO(this, uiGID);
    PREPARE_PLAYER_DETAIL_INFO(this, uiGID);
    PREPARE_PLAYER_DETAIL_EX1_INFO(this, uiGID);
    PREPARE_PLAYER_ONLINE_DATA(this, uiGID);

    int iIndex = 0;
    iIndex = pstMainCtrl->m_stPlayerBaseInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerBaseInfo& stPlayerBaseInfo = pstMainCtrl->m_stPlayerBaseInfoHash[iIndex];

    if (stPlayerBaseInfo._ucIsInited != 1)
    {
        return AnsClients(ERROR_NOT_INITED);
    }

    iIndex = pstMainCtrl->m_stPlayerDetailInfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("online user %u has no detail info", uiGID));
        return AnsClients(RET_SYSTEM_FAIL);
    }
    CPlayerDetailInfo& stPlayerDetailInfo = pstMainCtrl->m_stPlayerDetailInfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerDetailEx1InfoHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerDetailInfoEx1 & stPlayerDetailInfoEx1 = pstMainCtrl->m_stPlayerDetailEx1InfoHash[iIndex];

    iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
    if (iIndex < 0)
    {
        CT_ERROR(("gid = %u", uiGID));
        return AnsClients(RET_SYS_ERROR);
    }
    CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];

    switch (stReq.opt())
    {
    case 1:
        {
            pstMainCtrl->m_stQQMallMgr.GetMallTabContext(stPlayerDetailInfoEx1._stUserMall, (EN_MALL_TAB_TYPE)stReq.tab_type(), stAns);
        }
        break;

    case MALL_OPT_OWN:
        {
            //检查
            iRet = PreCheckBeforBuy (stPlayerOnlineData, stPlayerBaseInfo, stPlayerDetailInfoEx1);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            //扣费
            iRet = pstMainCtrl->m_stItemMgr.SubGold(stPlayerBaseInfo, OSS_MONEY_MODULE_11, _iTotalPirce);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            //发货
            CDropItem stDropItem;
            iRet = pstMainCtrl->m_stShopMgr.DeliverGoods(stPlayerOnlineData, stPlayerBaseInfo, stPlayerDetailInfo, stPlayerDetailInfoEx1,
                _uiGoodsID, _iBuyNum, DELIVER_GOODS_OWN, stDropItem);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            //记录oss统计
            pstMainCtrl->m_stOssMgr.TriggerMoney(uiGID, OSS_MONEY_INNER_BUY, _uiGoodsID, _iBuyNum);

            //保存数据
            CVarObjectKey stKey;
            stKey.m_chDataType = DT_PLAYER_BASE_INFO;
            stKey.m_u64ID = stPlayerBaseInfo._uiGID;
            pstMainCtrl->UpdateData(stKey, stPlayerBaseInfo, VOP_UPDATE);

            stDropItem.GetPBMsg(uiGID, *(stAns.mutable_gained_items()));
            pstMainCtrl->m_stNotifyMgr.Notify(uiGID, NOTIFY_USER_MONEY);
        }
        break;

    case MALL_OPT_QQ:
        {
            //检查
            iRet = PreCheckBeforBuy (stPlayerOnlineData, stPlayerBaseInfo, stPlayerDetailInfoEx1);
            if (iRet)
            {
                return AnsClients(iRet);
            }

            //获取本次交易的token
            CCmdApi* pstCmd = (CCmdApi*)CT_CMDFACTORY->CreateCmd(ID_MAINAPI_TAPI);
            if (!pstCmd)
            {
                CT_WARNING(("create cmd error"));
                return AnsClients(RET_SYS_ERROR);
            }

            pstCmd->stReq._stTApiKeyValue = stPlayerOnlineData._stTencentApiKeyValue;
            iRet = pstMainCtrl->m_stQQMallMgr.InitBuyGoodsCmd(_uiGoodsID, _iBuyNum, _iMaxNum, pstCmd);
            if (iRet)
            {
                pstCmd->Done(RET_OK);
                return AnsClients(iRet);
            }

            RegisterChild(pstCmd);
            return pstCmd->Do(NULL);
        }

        break;

    default:
        break;
    }

    return AnsClients(iRet);
}

int CCmdQQMall::CallBack(int iRet)
{
    if (iRet != RET_OK)
    {
        return AnsClients(iRet);
    }

    //解析平台信息
    if (m_pstChild && ID_MAINAPI_TAPI == m_pstChild->GetCmdID())
    {
        CCmdApi* pstCmd = (CCmdApi*)m_pstChild;

        //保存支付token
        int iIndex = pstMainCtrl->m_stPlayerOnlineDataHash.HashFind(uiGID);
        if (iIndex < 0)
        {
            CT_ERROR(("gid = %u", uiGID));
            return AnsClients(RET_SYS_ERROR);
        }
        CPlayerOnlineData& stPlayerOnlineData = pstMainCtrl->m_stPlayerOnlineDataHash[iIndex];
        stPlayerOnlineData._szTencentPayToken.Set("%s", pstCmd->stAns._stTApiKeyValue.GetValue("token"));

        //返回结果
        stAns.set_url_params(pstCmd->stAns._stTApiKeyValue.GetValue("url_params"));

        return AnsClients(iRet);
    }
    else
    {
        CT_ERROR((""));
        return AnsClients(RET_SYS_ERROR);
    }
}

int CCmdQQMall::AnsClients(int iRet)
{
    stMsgHead.set_msgret(iRet);
    stMsgHead.set_msgtype(CSMsgDef::EMT_ANSWER);

    if (iRet != RET_OK)
    {
        pstMainCtrl->ReturnMsgHead(stMsgHead, stEnpHead);
        return Done(iRet);
    }

    stAns.set_opt(stReq.opt());
    stAns.set_tab_type(stReq.tab_type());
    stAns.set_goods_id(stReq.goods_id());
    pstMainCtrl->m_stEncodeBuf.Clear();
    pstMainCtrl->EncodePBMsg(stMsgHead, pstMainCtrl->m_stEncodeBuf);
    pstMainCtrl->EncodePBMsg(stAns, pstMainCtrl->m_stEncodeBuf);
    if (pstMainCtrl->AnswerToClient(stEnpHead, pstMainCtrl->m_stEncodeBuf, true))
    {
        CT_WARNING((""));
        return Done(RET_SYS_ERROR);
    }

    return Done(iRet);
}

int CCmdQQMall::PreCheckBeforBuy(CPlayerOnlineData & stPlayerOnlineData, CPlayerBaseInfo & stPlayerBaseInfo, CPlayerDetailInfoEx1 & stPlayerDetailInfoEx1)
{
    _uiGoodsID = stReq.goods_id();
    if (0 == stReq.tab_type())
    {
        _uiGoodsID = pstMainCtrl->m_stQQMallMgr.GetQuickBuyGoodsId(stReq.item_type(), stReq.item_cfg_id());
    }

    if (false == pstMainCtrl->m_stQQMallMgr.IsValidGoodsId(_uiGoodsID))
    {
        return ERROR_QQMALL_GOODS_ID;
    }

    _iBuyNum = CT_MAX(stReq.num(), 1);
    if (pstMainCtrl->m_stQQMallMgr.IsLimitGoods(_uiGoodsID))
    {
        //检查用户是否购买的物品数，是否超量了
        _iMaxNum = pstMainCtrl->m_stQQMallMgr.GetMaxBuyNum (stPlayerDetailInfoEx1._stUserMall, _uiGoodsID, pstMainCtrl->m_iNow);
        if (_iMaxNum < _iBuyNum)
        {
            return ERROR_QQMALL_LIMTED_BUYNUMS;
        }
    }

    //成长基金
    if (_uiGoodsID == GROW_FUND_GOODS_ID)
    {
        //检查系统开启
        if (!pstMainCtrl->m_stCommConfigLoader.IsOpen(SYS_OPEN_COND_ID_46, stPlayerBaseInfo, stPlayerOnlineData))
        {
            return ERROR_SYS_NOT_OPEN;
        }

        if (stPlayerBaseInfo._shLevel >= 40)
        {
            return ERROR_SYS_NOT_OPEN;
        }

        //检查是否已经购买
        if (stPlayerDetailInfoEx1._stPayActData._ucHasBuyGrowFund != 0)
        {
            return ERROR_GROW_FUND_ERROR4;
        }

        _iBuyNum = 1; //最多只能买一个
    }

    if (_uiGoodsID != GROW_FUND_GOODS_ID) //成长基金不检查背包
    {
        CDropItem stDropItem;
        int iRet = pstMainCtrl->m_stQQMallMgr.GetMallDropGoods(_uiGoodsID, _iBuyNum, stDropItem);
        CHECK_RETURN(iRet);

        int iNeedSpace = stDropItem.GetSpaceSize();
        if (iNeedSpace > 0)
        {
            int iFreeGrid = stPlayerOnlineData._stUserStorage.GetFreeGridCount(true);
            if (MALL_OPT_OWN != stReq.opt() && iFreeGrid < 4)
            {
                return ERROR_BAG_WILL_FULL;
            }

            if (false == stDropItem.HasEnoughSpace(uiGID))
            {
                return ERROR_BAG_WILL_FULL;
            }
        }
    }

    const CMallGoodsUnit & stGoodsCfg = pstMainCtrl->m_stQQMallMgr.GetGoodUnit(_uiGoodsID);

    _iTotalPirce = _iBuyNum * stGoodsCfg._iRealCost;

    if (MALL_OPT_OWN == stReq.opt())
    {
        if (stPlayerBaseInfo._iGold < _iTotalPirce)
        {
            return ERROR_GOLD_LESS;
        }
    }

    //检查主角是否达到获取坐骑需要的等级
    if (MALL_TAB_MOUNT == stReq.tab_type())
    {
        if (ITEM_TYPE_MOUNT != stGoodsCfg._ucItemType)
        {
            return ERROR_MOUNT_SHOP_CONFIG;
        }
    }

    return RET_OK;
}
